home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / boot / czesc_2 / saferpatches / source.lha / Source / ShowPatch.c < prev    next >
C/C++ Source or Header  |  1992-10-04  |  12KB  |  383 lines

  1. typedef char CHAR;
  2. #define LOCAL static
  3. #define AND &&
  4. #define OR ||
  5.  
  6. #define TEXTLENGTH 50
  7. #define KICK204    37
  8. #define ESC_KEY    27
  9.  
  10. /**************************************************************************/
  11. /*  LibHeader                                  */
  12. /*     NextLib:  Next library in a linked list.               */
  13. /*     LibBase:  Pointer to the libraries base (e.g. intuitionbase).      */
  14. /*     Patches:  Pointer to linked list of patches made to this library.  */
  15. /**************************************************************************/
  16. struct LibHeader {
  17.   struct Library    *LibBase;
  18.   struct Patches    *Patches;
  19.   struct LibHeader  *NextLib;
  20. };
  21.  
  22. /************************************************************************/
  23. /*  Patches                                */
  24. /*     JMP    : Opcode for JMP (used to call the old function).       */
  25. /*     OldFunc    : Address to the previus function (before SetFunction). */
  26. /*     NewFunc    : The new function.                    */
  27. /*     Offset    : Offset in library (Must be negativ).                  */
  28. /*     NextPatch: Pointer to next patch in list.            */
  29. /************************************************************************/
  30. struct Patches {
  31.   USHORT      JMP;
  32.   LONG          OldFunc;
  33.   LONG          NewFunc;
  34.   SHORT       Offset;
  35.   struct Patches *NextPatch;
  36. };
  37.  
  38. /**************************************************************************/
  39. /*  MyNode    - is used to hold data to show.               */
  40. /*     ExecNode : Standard exec node structure                  */
  41. /*     Text    : array to put text inside (ExecNode.ln_Name points here) */
  42. /**************************************************************************/
  43. struct MyNode {
  44.   struct Node ExecNode;
  45.   char     Text[TEXTLENGTH];
  46. };
  47.  
  48. /************************/
  49. /* All local functions    */
  50. /************************/
  51. LOCAL VOID OpenFD(STRPTR LibName); /* Open .fd file corresponding to Libname */
  52. LOCAL BOOL GetLine(CHAR *Buffer);  /* Read one complete line from .fd file   */
  53. LOCAL VOID CloseFD(VOID);          /* Close the .fd file                     */
  54.  
  55. LOCAL VOID BuildList(BOOL);        /* Build the list of all known patches    */
  56. LOCAL VOID DestroyList(VOID);      /* Remove the list                        */
  57. LOCAL CHAR *AddNewNode(VOID);      /* Create a new node and add it to the list */
  58.  
  59.  
  60. LOCAL BOOL FindOffset(CHAR *BUFFER, SHORT OffsetToFind);  /* Finds the function name */
  61. LOCAL VOID OutputToWindow(VOID);   /* Outputs in our own window              */
  62. LOCAL VOID OutputToCLI(VOID);      /* Outputs to CLI (may be redirected      */
  63.  
  64. /******************************/
  65. /* The only exported function */
  66. /******************************/
  67. VOID MainLoop(BOOL,BOOL);
  68.  
  69. /******************************/
  70. /* Our assembler functions    */
  71. /******************************/
  72. extern struct LibHeader *FindPatches(VOID);   /* Finds the SaferPatches program */
  73.  
  74. extern struct Window *OpenWindowWithGad(VOID);          /* Open our window     */
  75. extern VOID CloseWindowWithGad(struct Window *Window);  /* Closes our window   */
  76.  
  77. extern VOID Bin2Hex(CHAR *, ULONG, UWORD);    /* converts a long to ascii hex  */
  78.  
  79. extern VOID  Mystrncpy(CHAR *, CHAR *, UWORD);  /* a small and fast strncpy */
  80.  
  81. /************************************************/
  82. /* I dont have the 2.04 C includes so I have to */
  83. /* declare the new functions here        */
  84. /************************************************/
  85. struct IntuiMessage *GT_GetIMsg(struct Port *);
  86. VOID GT_ReplyIMsg(struct IntuiMessage *);
  87.  
  88. VOID GT_BeginRefresh(struct Window *);
  89. VOID GT_EndRefresh(struct Window *, BOOL);
  90.  
  91. CHAR FGetC(BPTR);
  92. VOID StrToLong(CHAR *, ULONG *);
  93.  
  94. VOID WriteChars(CHAR *, ULONG);
  95. VOID PutStr(CHAR *);
  96.  
  97. /************************************/
  98. /* Pragmas for the above functions  */
  99. /************************************/
  100. #pragma libcall GadToolsBase GT_GetIMsg 48 801
  101. #pragma libcall GadToolsBase GT_ReplyIMsg 4e 901
  102. #pragma libcall GadToolsBase GT_BeginRefresh 5a 801
  103. #pragma libcall GadToolsBase GT_EndRefresh 60 802
  104. #pragma libcall DOSBase FGetC 132 101
  105. #pragma libcall DOSBase StrToLong 330 2102
  106. #pragma libcall DOSBase WriteChars 3ae 2102
  107. #pragma libcall DOSBase PutStr 3b4 101
  108.  
  109. #define IDCMP_CLOSEWINDOW   CLOSEWINDOW
  110. #define IDCMP_GADGETUP        GADGETUP
  111. #define IDCMP_VANILLAKEY    0x200000L
  112. #define IDCMP_REFRESHWINDOW REFRESHWINDOW
  113.  
  114. /********************/
  115. /* Global variables */
  116. /********************/
  117. extern BPTR  Fh;       /* File handle for .fd file           */
  118. extern LONG  FDOffset;       /* How far we have read in the .fd file */
  119.  
  120. extern struct Library *GadToolsBase;         /* Library base */
  121. extern struct DOSBase *DOSBase;          /* Library base */
  122. extern struct IntuitionBase *IntuitionBase;  /* Library base */
  123.  
  124. extern struct List List;    /* Exec list of ascii strings */
  125.  
  126. /****************************************************************/
  127. /* MainProg(NoFD,UseWindow)                                     */
  128. /*   NoFD    - TRUE if we shouldn't look for FD files.       */
  129. /*   UseWIndow    - if TRUE open a window else output to console    */
  130. /****************************************************************/
  131. VOID MainLoop(BOOL NoFD, BOOL UseWindow) {
  132.  
  133.   BuildList(NoFD);
  134.  
  135.   if (UseWindow)
  136.     OutputToWindow();
  137.   else
  138.     OutputToCLI();
  139.  
  140.   DestroyList();
  141. }
  142.  
  143. /****************************************************************/
  144. /* OutputToWindow()  - create a window with a LISTVIEW gadget   */
  145. /*             - and present all patches there        */
  146. /****************************************************************/
  147. LOCAL VOID OutputToWindow() {
  148.   BOOL KeepRunning = TRUE;
  149.   struct Window *Window;
  150.  
  151.   if (IntuitionBase = (struct IntuitionBase *)
  152.               OpenLibrary("intuition.library",KICK204)) {
  153.  
  154.     if (GadToolsBase  = OpenLibrary("gadtools.library",KICK204)) {
  155.  
  156.       if (Window = OpenWindowWithGad()) {
  157.     do {
  158.       struct IntuiMessage *Msg;
  159.  
  160.       WaitPort(Window->UserPort);
  161.  
  162.       while (Msg = GT_GetIMsg(Window->UserPort)) {
  163.         ULONG Class = Msg->Class;
  164.  
  165.         if (Class & (IDCMP_CLOSEWINDOW | IDCMP_GADGETUP))
  166.           KeepRunning = FALSE;
  167.         else if (Class & IDCMP_VANILLAKEY) {
  168.           UWORD Code = Msg->Code;
  169.  
  170.           if (Code == ESC_KEY  OR  Code == 'X'  OR  Code == 'x')
  171.         KeepRunning = FALSE;
  172.           else
  173.         DisplayBeep(Window->WScreen);
  174.         }
  175.         else if (Class & IDCMP_REFRESHWINDOW) {
  176.           GT_BeginRefresh(Window);
  177.           GT_EndRefresh(Window,TRUE);
  178.         }
  179.         GT_ReplyIMsg(Msg);
  180.       }
  181.     }
  182.     while (KeepRunning);
  183.  
  184.     CloseWindowWithGad(Window);
  185.       }
  186.       CloseLibrary(GadToolsBase);
  187.     }
  188.     CloseLibrary((struct Library *)IntuitionBase);
  189.   }
  190. }
  191.  
  192. /******************************************************************/
  193. /* OutputToCLI()   - output all data to the default output stream */
  194. /******************************************************************/
  195. LOCAL VOID OutputToCLI() {
  196.   extern CHAR far LISTTEXT[];
  197.  
  198.   struct MyNode *Node;
  199.  
  200.   WriteChars(LISTTEXT,32);
  201.   PutStr("\n");
  202.   for (Node = (struct MyNode *)(List.lh_Head); Node->ExecNode.ln_Succ;
  203.        Node = (struct MyNode *)(Node->ExecNode.ln_Succ)) {
  204.     PutStr(Node->Text);
  205.     PutStr("\n");
  206.   }
  207. }
  208.  
  209. /************************************************************************/
  210. /* VOID BuildList(NoFD)     - Build up a list of nodes each containing  */
  211. /*                  an ascii string describing one patch made */
  212. /*    NoFD  - TRUE if we shouldn't look for .fd files                   */
  213. /************************************************************************/
  214. LOCAL VOID BuildList(BOOL NoFD) {
  215.   struct LibHeader *LocHeader;
  216.  
  217.   NewList(&List);
  218.  
  219.   if ((LocHeader = FindPatches()) != NULL) {
  220.     Forbid();
  221.  
  222.     while (LocHeader = LocHeader->NextLib) {
  223.       struct Patches *Patch = LocHeader->Patches;
  224.       STRPTR          LibName = LocHeader->LibBase->lib_Node.ln_Name;
  225.       CHAR          FuncName[200]; /* hope this is enough */
  226.       CHAR         *NodeText;
  227.  
  228.       if (NodeText = AddNewNode()) {
  229.     strcpy(NodeText, "Library: ");
  230.     Mystrncpy(NodeText+9, LibName, TEXTLENGTH-10);
  231.  
  232.     Fh = FDOffset = 0;
  233.  
  234.     if (!NoFD)
  235.       OpenFD(LibName);
  236.  
  237.     while (Patch = Patch->NextPatch) {
  238.       if (NodeText = AddNewNode()) {
  239.         Bin2Hex(NodeText   , (ULONG)(-Patch->Offset), 4);
  240.         Bin2Hex(NodeText+ 6, Patch->NewFunc, 8);
  241.         Bin2Hex(NodeText+16, Patch->OldFunc, 8);
  242.         NodeText[4]  = NodeText[5]    = NodeText[14] = NodeText[15] =
  243.         NodeText[24] = NodeText[25] = ' ';
  244.  
  245.         if (FindOffset(FuncName,-Patch->Offset))
  246.           Mystrncpy(NodeText+26, FuncName, TEXTLENGTH-27);
  247.       } /* if */
  248.     } /* while */
  249.     CloseFD();
  250.       } /* if */
  251.     } /* while */
  252.     Permit();
  253.   } /* if */
  254.   else {
  255.     CHAR *NodeText;
  256.  
  257.     if (NodeText = AddNewNode())
  258.       strcpy(NodeText," SaferPatches not installed !");
  259.   }
  260. }
  261.  
  262. /**********************************************************/
  263. /* AddNewNode()   - Create a new node and add it the list */
  264. /*   return  - pointer to MyMode textfield          */
  265. /**********************************************************/
  266. LOCAL CHAR *AddNewNode(VOID) {
  267.   struct MyNode *Node = AllocMem(sizeof(struct MyNode),MEMF_CLEAR);
  268.  
  269.   if (Node) {
  270.     AddTail(&List,&Node->ExecNode);
  271.     return (Node->ExecNode.ln_Name = Node->Text)
  272.   }
  273.   return NULL;
  274. }
  275. /**********************************************************/
  276. /* DestroyList()  - remove all nodes and free memory used */
  277. /**********************************************************/
  278. LOCAL VOID DestroyList() {
  279.   struct Node *Node;
  280.   struct Node *Temp;
  281.  
  282.   Node = List.lh_Head;
  283.  
  284.   while (Temp = Node->ln_Succ) {
  285.     FreeMem(Node,sizeof(struct MyNode));
  286.     Node = Temp;
  287.   }
  288. }
  289.  
  290. /********************************************************************************/
  291. /* BOOL FindOffset(Buffer, OffsetToFind) - Walk through the open .fd file until */
  292. /*                   we find the function corresponding to offset */
  293. /*    Buffer        - Where to store function name                */
  294. /*    OffSetToFind  -                                */
  295. /*    return        - TRUE if function found                    */
  296. /********************************************************************************/
  297. LOCAL BOOL FindOffset(CHAR *Buffer, SHORT OffsetToFind) {
  298.   extern CHAR far StdFunctions[];
  299.  
  300.   if (OffsetToFind < 30) {
  301.     strcpy(Buffer,StdFunctions+((OffsetToFind-6)<<1));
  302.     return TRUE;
  303.   }
  304.   while (OffsetToFind > (SHORT)FDOffset) {
  305.     FDOffset += 6;
  306.  
  307.     FOREVER {
  308.       if (GetLine(Buffer))
  309.     return FALSE;
  310.       if (Buffer[0] == '#') { /* command */
  311.     if (*((ULONG *)(Buffer+2)) == 0x62696173L)  /* bias */
  312.       StrToLong(Buffer+6,&FDOffset);
  313.       }
  314.       else if (Buffer[0] > ' ' AND Buffer[0] != '*')
  315.     break;
  316.     }
  317.   }
  318.  
  319.   /* remove anything beyond the first '(' */
  320.   if (OffsetToFind == (SHORT)FDOffset) {
  321.     while (*Buffer AND *Buffer != '(')
  322.       Buffer++;
  323.     *Buffer = 0;
  324.     return TRUE;
  325.   }
  326.   return FALSE;
  327. }
  328.  
  329. /*********************************************************/
  330. /* OpenFD(LibName)  - Open a .fd file                    */
  331. /*   Libname - library (or device) to open .fd file for. */
  332. /*********************************************************/
  333. LOCAL VOID OpenFD(STRPTR LibName) {
  334.   TEXT     FDFile[TEXTLENGTH];
  335.   CHAR    *Temp = FDFile;
  336.  
  337.   strcpy(FDFile,"FD:");
  338.   strcpy(FDFile+3,LibName);
  339.  
  340.   while (*Temp != '.')
  341.     Temp++;
  342.   strcpy(Temp,"_lib.fd");
  343.  
  344.   Fh = Open(FDFile, MODE_OLDFILE);
  345. }
  346.  
  347. /********************************************/
  348. /* CloseFD()  - Closes the current .fd file */
  349. /********************************************/
  350. LOCAL VOID CloseFD() {
  351.   if (Fh) {
  352.     Close(Fh);
  353.     Fh = NULL;
  354.   }
  355. }
  356.  
  357. /*****************************************************************/
  358. /* BOOL GetLine(Buffer)  - Reads one line from the open .fd file */
  359. /*   Buffer - where to store the line                 */
  360. /*   return - TRUE if end of file (EOF)                          */
  361. /*****************************************************************/
  362. LOCAL BOOL GetLine(CHAR *Buffer) {
  363.  
  364.   if (Fh) {
  365.     CHAR tkn;
  366.  
  367.     do {
  368.       tkn = FGetC(Fh);
  369.       if (tkn == EOF) {
  370.     CloseFD();
  371.     return TRUE;
  372.       }
  373.     }
  374.     while ((*Buffer++ = tkn) != '\n');
  375.     *Buffer = 0;
  376.     return FALSE;
  377.   }
  378.   return TRUE;
  379. }
  380.  
  381.  
  382.  
  383.